// hdu5852
// 题意：
// 给定一个n*n(<=100000)的棋盘，初始第一行有k(<=100)个点分别在(1, a1), (2, a2)...
// 然后要去第n行的对应k个点, (n, b1), (n, b2), ...
// 1<=a1<a2<...<an<=n， 1<=b1<b2<...<bn<=n，
// 现在每个棋子只能往下或者往右，问最后路径不相交不同的方案数。
//
// 题解：
// 考虑k=2，方案数是C(b1-a1+n-1, n-1)*C(b2-a2+n-1, n-1)，但是路径可能有
// 相交，减去相交的方案 C(b2-a1+n-1, n-1)*C(b1-a2+n-1, n-1)。
// 一般的，对于k个，相当于求这个行列式
// |A(i, j)| = |C(bj-ai+n-1, n-1)|
//
// 其实我们可以这样考虑，首先从第一行映射到第n行一共有n!种方案，但是怎么
// 决定某一种是+还是-呢，这就要看这个排列逆序对的个数，如果逆序对个数是偶数，
// 那么是正贡献，奇数负贡献，这就是对应行列式的定义，所以可以构造出行列式，
// 然后用高斯消元求解就好。
//
// 更一般的定理参考，
// https:/en.wikipedia.org/wiki/Lindstr%C3%B6m%E2%80%93Gessel%E2%80%93Viennot_lemma/
//
// ml:run = $bin < input > output
#include <iostream>
#include <algorithm>
#include <vector>

using ll = long long;
int const maxn = 200007;
ll const mo = 1000000007;
ll fact[maxn];
ll inverse[maxn];
int a[maxn], b[maxn];
int n, k;

std::vector<std::vector<ll>> det;

ll quick(ll a, ll b, ll mo)
{
    ll ret = 1;
    for (; b; a = (a * a) % mo, b /= 2)
        if (b & 1) ret = (ret * a) % mo;
    return ret;
}

void init()
{
    fact[0] = 1;
    for (int i = 1; i < maxn; i++) fact[i] = (fact[i - 1] * i) % mo;
    inverse[maxn - 1] = quick(fact[maxn - 1], mo - 2, mo);
    for (int i = maxn - 2; i >= 0; i--)
        inverse[i] = (inverse[i + 1] * (i + 1)) % mo;
}

ll combine(ll n, ll m)
{
    if (m > n) return 0;
    ll ret = (fact[n] * inverse[m]) % mo;
    return (ret * inverse[n - m]) % mo;
}

template <class T>
T abs(T x) { return x < 0 ? -x : x; }

void extended_gcd(ll a, ll b, ll & d, ll & x, ll & y)
{
	if (!b) { d = a; x = 1; y = 0; }
	else {
		extended_gcd(b, a % b, d, y, x);
		y -= x * (a/b);
	}
}

ll inv(ll t, ll p)
{
	ll x, y, d;
	extended_gcd(t, p, d, x, y);
	return (x % p + p) % p;
}

template <class T>
ll calc_det(std::vector<std::vector<T>> & a)
{
    ll ret = 1;
    int n = a.size();
    for (int i = 0; i < n ; i++) {
        int k = i;
        for (int j = i + 1; j < n; j++)
            if (abs(a[j][i]) > abs(a[k][i])) k = j;
        if (abs(a[k][i]) == 0) { ret = 0; break; }

        std::swap(a[i], a[k]);
        if (i != k) ret = -ret;
        ret = (ret * a[i][i]) % mo;

        for (int j = i + 1; j < n; j++)
            a[i][j] = (a[i][j] * inv(a[i][i], mo)) % mo;

        for (int j = 0; j < n; j++)
            if (j != i && abs(a[j][i]) > 0)
                for (int k = i + 1; k < n; k++) {
                    a[j][k] -= (a[i][k] * a[j][i]) % mo;
                    a[j][k] = (a[j][k] + mo) % mo;
                }
    }
    ret %= mo;
    return (ret + mo) % mo;
}

int main()
{
    std::ios_base::sync_with_stdio(false);
    init();
    int T; std::cin >> T;
    while (T--) {
        std::cin >> n >> k;
        det.resize(k);
        det.assign(k, std::vector<ll>(k));
        for (int i = 0; i < k; i++) std::cin >> a[i];
        for (int i = 0; i < k; i++) std::cin >> b[i];

        bool ok = true;
        for (int i = 0; i < k; i++)
            if (a[i] > b[i]) { ok = false; break; }
        if (!ok) { std::cout << "0\n"; continue; }

        for (int i = 0; i < k; i++)
            for (int j = 0; j < k; j++)
                det[i][j] = combine(b[j] - a[i] + n - 1, n - 1);
        std::cout << calc_det(det) << "\n";
    }
}

